#ifndef WINDOWSFUNCTIONS_H
#define WINDOWSFUNCTIONS_H

#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))
 #define _WIN32
#endif /* _WIN32 */


#ifdef _WIN32

#include "glext.h"


PFNGLGENBUFFERSPROC glGenBuffers = NULL;
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
PFNGLBUFFERDATAPROC glBufferData = NULL;

PFNGLACTIVETEXTUREARBPROC        glActiveTextureARB        = NULL;
PFNGLCREATEPROGRAMOBJECTARBPROC  glCreateProgramObjectARB  = NULL;
PFNGLDELETEOBJECTARBPROC         glDeleteObjectARB         = NULL;
PFNGLUSEPROGRAMOBJECTARBPROC     glUseProgramObjectARB     = NULL;
PFNGLCREATESHADEROBJECTARBPROC   glCreateShaderObjectARB   = NULL;
PFNGLSHADERSOURCEARBPROC         glShaderSourceARB         = NULL;
PFNGLCOMPILESHADERARBPROC        glCompileShaderARB        = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
PFNGLATTACHOBJECTARBPROC         glAttachObjectARB         = NULL;
PFNGLGETINFOLOGARBPROC           glGetInfoLogARB           = NULL;
PFNGLLINKPROGRAMARBPROC          glLinkProgramARB          = NULL;
PFNGLGETUNIFORMLOCATIONARBPROC   glGetUniformLocationARB   = NULL;
PFNGLUNIFORM4FARBPROC            glUniform4fARB            = NULL;
PFNGLUNIFORM1FARBPROC            glUniform1fARB            = NULL;
PFNGLUNIFORM1IARBPROC            glUniform1iARB            = NULL;
PFNGLUNIFORMMATRIX4FVARBPROC        glUniformMatrix4fvARB     = NULL;

#endif

/*
 * loadExtensions - Load all OpenGL functions we use beyond version 1.1.
 * (This could be handled by an extension loader library, e.g GLEW.)
 * On any platform except Windows, this is not needed.
 */
void loadExtensions() {
  #ifdef _WIN32
	// These extension strings indicate that the OpenGL Shading Language,
	// GLSL shader objects and floating-point textures are supported.
	if(!glfwExtensionSupported("GL_ARB_shading_language_100"))
    {
		//printError("GL init error", "GL_ARB_shading_language_100 extension was not found");
		return;
    }
	if(!glfwExtensionSupported("GL_ARB_shader_objects"))
    {
		//printError("GL init error", "GL_ARB_shader_objects extension was not found");
		return;
    }
	// else
    glGenBuffers = (PFNGLGENBUFFERSPROC)glfwGetProcAddress("glGenBuffers");
    glBindBuffer = (PFNGLBINDBUFFERPROC)glfwGetProcAddress("glBindBuffer");
    glBufferData = (PFNGLBUFFERDATAPROC)glfwGetProcAddress("glBufferData");
  
	glActiveTextureARB        = (PFNGLACTIVETEXTUREARBPROC)glfwGetProcAddress("glActiveTextureARB");
	glCreateProgramObjectARB  = (PFNGLCREATEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glCreateProgramObjectARB");
	glDeleteObjectARB         = (PFNGLDELETEOBJECTARBPROC)glfwGetProcAddress("glDeleteObjectARB");
	glUseProgramObjectARB     = (PFNGLUSEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glUseProgramObjectARB");
	glCreateShaderObjectARB   = (PFNGLCREATESHADEROBJECTARBPROC)glfwGetProcAddress("glCreateShaderObjectARB");
	glShaderSourceARB         = (PFNGLSHADERSOURCEARBPROC)glfwGetProcAddress("glShaderSourceARB");
	glCompileShaderARB        = (PFNGLCOMPILESHADERARBPROC)glfwGetProcAddress("glCompileShaderARB");
	glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glfwGetProcAddress("glGetObjectParameterivARB");
	glAttachObjectARB         = (PFNGLATTACHOBJECTARBPROC)glfwGetProcAddress("glAttachObjectARB");
	glGetInfoLogARB           = (PFNGLGETINFOLOGARBPROC)glfwGetProcAddress("glGetInfoLogARB");
	glLinkProgramARB          = (PFNGLLINKPROGRAMARBPROC)glfwGetProcAddress("glLinkProgramARB");
	glGetUniformLocationARB   = (PFNGLGETUNIFORMLOCATIONARBPROC)glfwGetProcAddress("glGetUniformLocationARB");
	glUniform4fARB            = (PFNGLUNIFORM4FARBPROC)glfwGetProcAddress("glUniform4fARB");
	glUniform1fARB            = (PFNGLUNIFORM1FARBPROC)glfwGetProcAddress("glUniform1fARB");
	glUniform1iARB            = (PFNGLUNIFORM1IARBPROC)glfwGetProcAddress("glUniform1iARB");
	glUniformMatrix4fvARB     = (PFNGLUNIFORMMATRIX4FVARBPROC)glfwGetProcAddress("glUniformMatrix4fvARB");
	
	if( !glActiveTextureARB ||
	   !glCreateProgramObjectARB || !glDeleteObjectARB || !glUseProgramObjectARB ||
	   !glCreateShaderObjectARB || !glCreateShaderObjectARB || !glCompileShaderARB || 
	   !glGetObjectParameterivARB || !glAttachObjectARB || !glGetInfoLogARB || 
	   !glLinkProgramARB || !glGetUniformLocationARB || !glUniform4fARB ||
	   !glUniform1fARB || !glUniform1iARB || !glUniformMatrix4fvARB)
    {
		printf( "One or more GL_ARB_shader_objects functions were not found");
		//printError("GL init error", "One or more GL_ARB_shader_objects functions were not found");
		return;
    }
#endif
}
#endif
